package com.wu.webflux4.authManager;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.ReactiveAuthorizationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.web.server.authorization.AuthorizationContext;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;


import reactor.core.publisher.Mono;

public class MyAuthorizationManager implements  ReactiveAuthorizationManager<AuthorizationContext>{
	
	private final AntPathMatcher antPathMatcher = new AntPathMatcher();
	private final Map<String, String> concurrentHashMap = new ConcurrentHashMap<>();
	
	public MyAuthorizationManager() {
		concurrentHashMap.put("/hello", "ROLE_USER");
		concurrentHashMap.put("/js/**", "whiter");
		concurrentHashMap.put("/actuator/**", "whiter");
		concurrentHashMap.put("/index", "whiter");
		concurrentHashMap.put("/logout", "whiter");
	}

	@Override
	public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, AuthorizationContext object) {
		ServerWebExchange exchange = object.getExchange();
		String requestPath = exchange.getRequest().getURI().getPath();
		System.out.println(requestPath);
		for (Map.Entry<String, String> entry : concurrentHashMap.entrySet()) {
			if(antPathMatcher.match(entry.getKey(), requestPath)) {
				if("whiter".equals(concurrentHashMap.get(entry.getKey()))) {
					return Mono.just(new AuthorizationDecision(true));
				}
			}
			
		}
		return authentication.map(auth ->{
			//用户权限
			Collection<? extends GrantedAuthority> authorities = auth.getAuthorities();
			//存储的路径需要的权限
			String checkAuth = concurrentHashMap.get(requestPath);
			boolean contains = authorities.contains(new SimpleGrantedAuthority(checkAuth));
			if(contains) {
				return new AuthorizationDecision(true);
			}else {
				for (Map.Entry<String, String> entry : concurrentHashMap.entrySet()) {
					if(antPathMatcher.match(entry.getKey(), requestPath)) {
						if(authorities.contains(new SimpleGrantedAuthority(concurrentHashMap.get(entry.getKey())))) {
							return new AuthorizationDecision(true);
						}
					}
					
				}
			}
			return new AuthorizationDecision(false);
			
        }).defaultIfEmpty(new AuthorizationDecision(false));
		
		
	}




}